package cn.hhy.hrm.service.Impl;


import cn.hhy.hrm.domain.CourseDoc;
import cn.hhy.hrm.dto.CourseSearchParamDTO;
import cn.hhy.hrm.mapper.HighlightResultMapper;
import cn.hhy.hrm.repository.CourseElasticSearchRepository;
import cn.hhy.hrm.service.ICourseESService;
import cn.hhy.hrm.util.PageList;
import cn.hhy.hrm.vo.AggPageListVO;
import cn.hhy.hrm.vo.AggrTermsVo;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class CourseESServiceImpl implements ICourseESService {

    @Autowired
    private CourseElasticSearchRepository courseElasticSearchRepository;

    @Autowired
    private ElasticsearchRestTemplate template;

    @Autowired
    private HighlightResultMapper mapper;




    @Override
    public void add(CourseDoc doc) {
        courseElasticSearchRepository.save(doc);
    }

    @Override
    public PageList<CourseDoc> searchCourse(CourseSearchParamDTO dto) {
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        builder.withPageable(PageRequest.of(dto.getPage()-1,dto.getRows()));

        if (StringUtils.isNotEmpty(dto.getSortField())) {
            String sort = "onlineTime";
            switch (dto.getSortField()) {
                case "xl":
                    sort = "saleCount";
                    break;
                case "xp":
                    sort = "onlineTime";
                    break;
                case "rq":
                    sort = "viewCount";
                    break;
                case "jg":
                    sort = "price";
                    break;
                case "pl":
                    sort = "commentCount";
                    break;

            }

            SortOrder sortOrder = SortOrder.DESC;
            if (StringUtils.isNotEmpty(dto.getSortType()) && dto.getSortType().equalsIgnoreCase("asc")) {
                sortOrder = SortOrder.ASC;
            }
            builder.withSort(new FieldSortBuilder(sort).order(sortOrder));
        }
            //==========查询条件
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            if (StringUtils.isNotEmpty(dto.getKeyword())) {

                boolQueryBuilder.must(QueryBuilders.matchQuery("name",dto.getKeyword()));
            }
            if (dto.getCourseTypeId()!=null) {
                boolQueryBuilder.filter(QueryBuilders.termQuery("courseTypeId",dto.getCourseTypeId()));

            }

            if (StringUtils.isNotEmpty(dto.getGradeName())) {
                boolQueryBuilder.filter(QueryBuilders.termQuery("gradeName",dto.getGradeName()));

            }
            if (dto.getPriceMax()!=null) {
                boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").lte(dto.getPriceMax()));

            }
            if (dto.getPriceMin()!=null) {
                boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(dto.getPriceMin()));

            }
            builder.withQuery(boolQueryBuilder);
            builder.withHighlightFields(new HighlightBuilder.Field("name").preTags("<font style='color:red' >").postTags("</font>"));

            builder.addAggregation(AggregationBuilders.terms("tenantAgg").field("tenantName"))
                    .addAggregation(AggregationBuilders.terms("gradeAgg").field("gradeName"));



        SearchQuery searchQuery = builder.build();
//        Page<CourseDoc> page = courseElasticSearchRepository.search(searchQuery);
        AggregatedPage<CourseDoc> page = template.queryForPage(searchQuery, CourseDoc.class, mapper);


        Aggregations tenantAgg = page.getAggregations();
        Map<String, Aggregation> stringAggregationMap = tenantAgg.asMap();


        Map<String, List<AggrTermsVo>> map = new HashMap<>();

        stringAggregationMap.entrySet().forEach(entry->{
            String aggName = entry.getKey();
            ParsedStringTerms value = (ParsedStringTerms) entry.getValue();

            List<? extends Terms.Bucket> buckets = value.getBuckets();
            List<AggrTermsVo> aggrTermsVos = new ArrayList<>();
            buckets.forEach(bucket->{
                AggrTermsVo aggrTermsVo = new AggrTermsVo();
                String keyAsString = bucket.getKeyAsString();
                long docCount = bucket.getDocCount();
                aggrTermsVo.setCount(docCount);
                aggrTermsVo.setKey(keyAsString);
                aggrTermsVos.add(aggrTermsVo);
            });

            map.put(aggName,aggrTermsVos);

        });

//        return new PageList<CourseDoc>(page.getTotalPages(),page.getContent());
        return new AggPageListVO(page.getTotalPages(),page.getContent(),map);
    }


}
